package com.snailwu.security.KeyPairGenerator;

import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.Map;

/**
 * @author WuQinglong
 * @date 2021/1/19 12:07
 */
public class RSAMain {

    // 加密算法
    private static final String algorithm = "RSA";

    public static void main(String[] args) throws Exception {
        // 待加密的数据
        String data = "admin";

        // 获取公钥私钥
        Map<String, String> rsaMap = KeyPairGeneratorMain.generate(algorithm, 2048);
        String privateKeyStr = rsaMap.get(KeyPairGeneratorMain.PRIVATE_KEY);
        String publicKeyStr = rsaMap.get(KeyPairGeneratorMain.PUBLIC_KEY);

        // 私钥加密
        String encryptStr = encrypt(privateKeyStr, data);
        System.out.println("私钥=>公钥：加密：" + encryptStr);

        // 公钥解密
        String decryptStr = decrypt(publicKeyStr, encryptStr);
        System.out.println("私钥=>公钥：解密：" + decryptStr);
    }

    private static String decrypt(String publicKeyStr, String encryptStr) throws Exception {
        // Base64解码
        byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyStr.getBytes());

        // 构造 KeyFactory 根据公钥串生成公钥对象
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        PublicKey publicKey = keyFactory.generatePublic(new X509EncodedKeySpec(publicKeyBytes));

        // Base64解码加密的数据
        byte[] decodeBytes = Base64.getDecoder().decode(encryptStr.getBytes());

        // 根据公钥对象进行解密
        Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, publicKey);
        byte[] decryptBytes = cipher.doFinal(decodeBytes);

        return new String(decryptBytes);
    }

    private static String encrypt(String privateKeyStr, String data) throws Exception {
        // Base64解码
        byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyStr.getBytes());

        // 构造 KeyFactory 根据私钥串生成私钥对象
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        PrivateKey privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKeyBytes));

        // 根据私钥对象进行加密
        Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        byte[] encryptBytes = cipher.doFinal(data.getBytes());

        // Base64编码
        return Base64.getEncoder().encodeToString(encryptBytes);
    }

}
